package com.java.dao.impl;

import com.java.bean.User;
import com.java.dao.BaseUserDao;
import com.java.exception.DuplicateException;
import com.java.util.DBUtil;
import com.java.exception.ExceptionStateEnum;

import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class UserDaoMysql extends DBUtil implements BaseUserDao {                                                                                               // language=MySQL
    private static final String SQL_CONSOLE =           "SELECT COUNT(1) SIZE,COUNT(TO_DAYS(REGTIME)=TO_DAYS(NOW()) OR NULL) DAY FROM users WHERE status=0 ";  // language=MySQL
    private static final String SQL_TOTAL =             "SELECT COUNT(1) FROM users WHERE status=0                                                         ";  // language=MySQL
    private static final String SQL_GET_USER_BY_PHONE = "SELECT * FROM users WHERE status=0 AND phone=?                                                   ";  // language=MySQL
    private static final String SQL_LOGIN =             "SELECT * FROM users WHERE status=0 AND name=? AND PASSWORD=?                                     ";  // language=MySQL
    private static final String SQL_GET_USER_BY_NAME =  "SELECT * FROM users WHERE status=0 AND name=?                                                    ";  // language=MySQL
    private static final String SQL_LIST_USER =         "SELECT * FROM users WHERE status=0 LIMIT ?,?                                                      ";  // language=MySQL
    private static final String SQL_INSERT =            "INSERT INTO users VALUES(NULL,?,?,?,?,?,0,?)                                                       ";  // language=MySQL
    private static final String SQL_UPDATE =            "UPDATE users SET name=?,phone=?,PASSWORD=?,status=?,email=? WHERE id=?                        ";  // language=MySQL
    private static final String SQL_DELETE =            "UPDATE users SET status=1,name=NULL,phone=NULL,email=NULL WHERE id=?                          ";  // language=MySQL
    private static final String SQL_UPDATE_LOGINTIME =  "UPDATE users SET LOGINTIME=NOW() WHERE id=?                                                       ";  // language=MySQL
    private static final String SQL_GET_USER_BY_EMAIL = "SELECT * FROM users WHERE status=0 AND email=?;                                                  ";


    /**
     * 控制台参数 size day
     *
     * @return 控制台参数
     */
    @Override
    public Map<String, Integer> console() {
        try {
            query(pps(SQL_CONSOLE), null);
            if (rs.next()){
                final Map<String, Integer> data = new HashMap<>();
                data.put("size", rs.getInt("SIZE"));
                data.put("day", rs.getInt("DAY"));
                return data;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            closeAll();
        }
        return null;
    }

    /**
     * 获取总条数
     *
     * @return 总条数
     */
    @Override
    public int total() {
        try {
            query(pps(SQL_TOTAL), null);
            return getCount();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            closeAll();
        }
        return -1;
    }

    /**
     * 用户登录，并修改登录时间
     *
     * @param name     用户名
     * @param password 密码
     * @return 登录成功返回用户信息，否则返回null
     */
    @Override
    public User login(String name, String password) {
        User user = null;
        try {
            List<Object> params = new ArrayList<>();
            params.add(name);
            params.add(password);
            query(pps(SQL_LOGIN), params);
            user = setOne(User.class);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            closeAll();
        }
        if (user != null) {
            try {
                update(pps(SQL_UPDATE_LOGINTIME), user.getId());
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                closeAll();
            }
        }
        return user;
    }

    /**
     * 根据用户名查找用户信息
     *
     * @param uname 用户名
     * @return 用户信息
     */
    @Override
    public User getUserByName(String uname) {
        return getUser(uname, SQL_GET_USER_BY_NAME);
    }

    /**
     * 根据用户手机号码用户信息
     *
     * @param uphone 用户手机号码
     * @return 用户信息
     */
    @Override
    public User getUserByPhone(String uphone) {
        return getUser(uphone, SQL_GET_USER_BY_PHONE);
    }

    /**
     * 列出用户
     *
     * @param offset     起始位置
     * @param pageNumber 查询数量
     * @return 用户集合
     */
    @Override
    public List<User> listUser(int offset, int pageNumber) {
        try {
            List<Object> params = new ArrayList<>();
            params.add(offset);
            params.add(pageNumber);
            query(pps(SQL_LIST_USER), params);
            return setAll(User.class);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            closeAll();
        }
        return null;
    }

    /**
     * 添加用户
     *
     * @param user 用户信息 参数：name phone email password regdate
     * @return 生成的键
     */
    @Override
    public int insert(User user) throws DuplicateException {
        try {
            List<Object> params = new ArrayList<>();
            params.add(user.getName());
            params.add(user.getPhone());
            params.add(user.getPassword());
            params.add(user.getRegtime());
            params.add(user.getLogintime());
            params.add(user.getEmail());
            update(pps(SQL_INSERT, Statement.RETURN_GENERATED_KEYS), params);
            rs = pps.getGeneratedKeys();
            return getCount();
        } catch (SQLException e) {
            throwException(e.getMessage());
            e.printStackTrace();
        } finally {
            closeAll();
        }
        return -1;
    }

    private void throwException(String message) throws DuplicateException {
        if (message.contains("name_u")) {
            throw new DuplicateException(ExceptionStateEnum.DUPLICATE_NAME);
        } else if (message.contains("phone_u")) {
            throw new DuplicateException(ExceptionStateEnum.DUPLICATE_PHONE);
        } else if (message.contains("email_u")) {
            throw new DuplicateException(ExceptionStateEnum.DUPLICATE_EMAIL);
        }
    }

    /**
     * 更新用户信息
     *
     * @param id      用户id
     * @param newUser 新的用户信息 参数：name phone email password
     * @return 影响行数
     */
    @Override
    public int update(int id, User newUser) throws DuplicateException {
        try {
            List<Object> params = new ArrayList<>();
            params.add(newUser.getName());
            params.add(newUser.getPhone());
            params.add(newUser.getPassword());
            params.add(newUser.getStatus());
            params.add(newUser.getEmail());
            params.add(id);
            return update(pps(SQL_UPDATE), params);
        } catch (SQLException e) {
            throwException(e.getMessage());
            e.printStackTrace();
        } finally {
            closeAll();
        }
        return -1;
    }

    /**
     * 删除用户（假删除）
     *
     * @param id 用户id
     * @return 影响行数
     */
    @Override
    public int delete(int id) {
        try {
            return update(pps(SQL_DELETE), id);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            closeAll();
        }
        return 0;
    }

    @Override
    public User getUserByEmail(String email) {
        return getUser(email, SQL_GET_USER_BY_EMAIL);
    }

    private User getUser(String param, String sqlGetUser) {
        try {
            List<Object> p = new ArrayList<>();
            p.add(param);
            query(getConnection().prepareStatement(sqlGetUser), p);
            return setOne(User.class);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            closeAll();
        }
        return null;
    }
}
